

/*
 * ChatGUI.java
 *
 * Created on 28 nov. 2013, 01:55:25
 */
package GUI;

import Controller.ChatController;
import Controller.Exceptions.ControllerPerformException;
import Controller.Interface.PerformInterface;
import GUI.Interface.ListObserveur;
import GUI.Interface.RefreshInterface;
import Messages.Settings.MessageSettings;
import Type.AudioSound;
import Type.Wizzer;
import System.ChatSystem;
import Model.Exceptions.PathFileException;
import Model.PathFile;
import Model.Status;
import java.awt.Color;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.BadLocationException;

/**
 *
 * @author      Frank Djomo
 * @author      Christelle SIAGO HAPPI
 * @author      djomopoueme@gmail.com
 * @author      christelle.siagohappi@gmail.com
 */
public class ChatGUI extends javax.swing.JFrame implements PerformInterface,RefreshInterface,ListObserveur  {



    /**
     * Constructeur
     */
    public ChatGUI() {
        listModel = new DefaultListModel();
        tabMap=new HashMap<String, Integer>();
        initComponents();
        this.color = new colorOnglet(tabbedPane);
        panels=new ChatPanel();
        nbTab=0;
    }

    /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tabbedPane = new javax.swing.JTabbedPane();
        barreEtat = new javax.swing.JLabel();
        scrollBarMsg = new javax.swing.JScrollPane();
        areaMsg = new javax.swing.JTextArea();
        scrollBarList = new javax.swing.JScrollPane();
        listContacts = new javax.swing.JList();
        buttonSend = new javax.swing.JButton();
        buttonFile = new javax.swing.JButton();
        labelStatus = new javax.swing.JLabel();
        labelWelcome = new javax.swing.JLabel();
        status = new javax.swing.JComboBox();
        menuBar = new javax.swing.JMenuBar();
        menuFichier = new javax.swing.JMenu();
        itemConnexion = new javax.swing.JMenuItem();
        itemDeconnexion = new javax.swing.JMenuItem();
        menuHelp = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("JChat");
        setIconImage(new javax.swing.ImageIcon(getClass().getResource("/Ressources/images/app.png")).getImage());
        setResizable(false);

        tabbedPane.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED, java.awt.Color.darkGray, java.awt.Color.lightGray), "Conversation", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Cambria", 0, 12), java.awt.Color.lightGray)); // NOI18N

        barreEtat.setFont(new java.awt.Font("Cambria", 0, 12));
        barreEtat.setText("Connecté");
        barreEtat.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        areaMsg.setColumns(20);
        areaMsg.setLineWrap(true);
        areaMsg.setRows(5);
        areaMsg.setWrapStyleWord(true);
        areaMsg.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        areaMsg.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                areaMsgKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                areaMsgKeyReleased(evt);
            }
        });
        scrollBarMsg.setViewportView(areaMsg);

        listContacts.setModel(listModel);
        listContacts.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        listContacts.setToolTipText("Liste des contacts");
        listContacts.setCellRenderer(new ContactListCellRender());
        listContacts.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                listContactsMouseClicked(evt);
            }
        });
        scrollBarList.setViewportView(listContacts);

        buttonSend.setFont(new java.awt.Font("Cambria", 0, 12));
        buttonSend.setForeground(new java.awt.Color(0, 153, 255));
        buttonSend.setText("Chat");
        buttonSend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonSendActionPerformed(evt);
            }
        });

        buttonFile.setFont(new java.awt.Font("Cambria", 0, 12));
        buttonFile.setForeground(new java.awt.Color(0, 153, 255));
        buttonFile.setText("File");
        buttonFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonFileActionPerformed(evt);
            }
        });

        labelStatus.setFont(new java.awt.Font("Cambria", 0, 14));
        labelStatus.setForeground(new java.awt.Color(0, 153, 204));
        labelStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Ressources/images/online.png"))); // NOI18N
        labelStatus.setText("Connecté");

        labelWelcome.setFont(new java.awt.Font("Cambria", 1, 14));
        labelWelcome.setForeground(new java.awt.Color(0, 153, 204));
        labelWelcome.setText("Bienvenue");

        status.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Connecté", "Absent" }));
        status.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                statusActionPerformed(evt);
            }
        });

        menuBar.setForeground(new java.awt.Color(0, 102, 255));
        menuBar.setFont(new java.awt.Font("Cambria", 0, 14));

        menuFichier.setForeground(new java.awt.Color(0, 153, 204));
        menuFichier.setText("Fichier");
        menuFichier.setFont(new java.awt.Font("Cambria", 0, 14));

        itemConnexion.setText("Se connecter");
        itemConnexion.setEnabled(false);
        menuFichier.add(itemConnexion);

        itemDeconnexion.setText("Se deconnecter");
        itemDeconnexion.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemDeconnexionActionPerformed(evt);
            }
        });
        menuFichier.add(itemDeconnexion);

        menuBar.add(menuFichier);

        menuHelp.setForeground(new java.awt.Color(0, 153, 204));
        menuHelp.setText("A propos");
        menuHelp.setFont(new java.awt.Font("Cambria", 0, 14));
        menuHelp.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                menuHelpMouseClicked(evt);
            }
        });
        menuBar.add(menuHelp);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(barreEtat, javax.swing.GroupLayout.DEFAULT_SIZE, 654, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(scrollBarList, javax.swing.GroupLayout.DEFAULT_SIZE, 223, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(labelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(status, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(40, 40, 40))
                    .addComponent(labelWelcome, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(scrollBarMsg, javax.swing.GroupLayout.PREFERRED_SIZE, 348, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(buttonFile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(buttonSend, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap())
                    .addComponent(tabbedPane)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(23, 23, 23)
                                .addComponent(buttonSend)
                                .addGap(20, 20, 20)
                                .addComponent(buttonFile))
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(scrollBarMsg, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(labelWelcome, javax.swing.GroupLayout.DEFAULT_SIZE, 40, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(labelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(status, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(scrollBarList, javax.swing.GroupLayout.PREFERRED_SIZE, 356, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(barreEtat, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void itemDeconnexionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemDeconnexionActionPerformed

       if(isConnected()){
            try {
                performDisonnect();
            } catch (ControllerPerformException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
               JOptionPane.showMessageDialog(this,"Erreur lors de la deconnexion","Deconnexion impossible",JOptionPane.ERROR_MESSAGE);  
            }
       }
       else
       {
           JOptionPane.showMessageDialog(this,"Veuillez vous connecter","Deconnexion impossible",JOptionPane.ERROR_MESSAGE);  
       }    }//GEN-LAST:event_itemDeconnexionActionPerformed

    private void menuHelpMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_menuHelpMouseClicked
        // TODO add your handling code here:

        String appName ="ChatSystem Insa\n";
        String appVersion = "1.0";
        String appBuild = "Decembre 2013";

        dialog = new AboutDialog(this,appName,appVersion,appBuild);
        dialog.setVisible(true);
    }//GEN-LAST:event_menuHelpMouseClicked

    private void areaMsgKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_areaMsgKeyPressed
        // TODO add your handling code here:
        //recuperation de l'onglet courant
        String rName=null;
        Onglet currentOnglet = (Onglet)tabbedPane.getSelectedComponent();
        if(currentOnglet != null)  rName = currentOnglet.getDestination();
        if(rName !=null && evt.getKeyCode()!=KeyEvent.VK_ENTER){
            try {
                    performComposing(rName,true);
            } catch (ControllerPerformException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
    }//GEN-LAST:event_areaMsgKeyPressed

    
    private void buttonSendActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSendActionPerformed
        try {
            this.sendMsg();
        } catch (BadLocationException ex) {
            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
           JOptionPane.showMessageDialog(this,"Une erreur est survenue","Erreur",JOptionPane.ERROR_MESSAGE);    

        }
    }//GEN-LAST:event_buttonSendActionPerformed

    
    private void buttonFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonFileActionPerformed
        if(listContacts.getSelectedIndex()!= -1){
                //choix du fichier et creation du PathFile
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Fichiers","txt"); 
                chooser.addChoosableFileFilter(filter);
                chooser.setFileFilter(filter);

                int returnVal = chooser.showOpenDialog(this);
                if(returnVal == JFileChooser.APPROVE_OPTION){  
                      try {

                        String filename = chooser.getSelectedFile().getPath(); 

                        PathFile file = new PathFile(filename);
                        String rName = (String)listModel.getElementAt(listContacts.getSelectedIndex());
                        String message = "Demande de tranfert de fichier envoyé à "+rName+" . . ." ;
                        barreEtat.setText(message);

                        performFileRequest(file, rName);

                      }      
                      catch (ControllerPerformException ex) {
                        Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                        JOptionPane.showMessageDialog(this,"Une erreur est survenue","Erreur",JOptionPane.ERROR_MESSAGE);    

                      }  
                      catch (PathFileException ex) {
                            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                            JOptionPane.showMessageDialog(this,"La taille du fichier est limitée à 1Mo","Erreur",JOptionPane.ERROR_MESSAGE);    
                       }               
                }   
        }
        else{
                JOptionPane.showMessageDialog(this,"Selectionnez un contact dans la liste","Aucun contact",JOptionPane.ERROR_MESSAGE);              
        }     }//GEN-LAST:event_buttonFileActionPerformed

    private void listContactsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_listContactsMouseClicked
        // TODO add your handling code here:
        if(evt.getClickCount()==1){
                    int index = listContacts.getSelectedIndex();
                    if(index != -1){
                        try {
                            String rName = (String)listModel.getElementAt(index);
                            if(!tabMap.containsKey(rName)){
                                Onglet onglet = new Onglet(rName);
                                tabbedPane.insertTab(rName, null, onglet, rName, nbTab);
                                tabMap.put(rName, Integer.valueOf(nbTab++));
                                this.color.startActivity();
                            }
                            else{
                                //Onglet onglet = new Onglet(rName); 
                                //onglet.requestFocusInWindow();
                            }
                        } catch (IOException ex) {
                            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                            JOptionPane.showMessageDialog(this,"Erreur survenue","Erreur",JOptionPane.ERROR_MESSAGE);              
                        } catch (URISyntaxException ex) {
                            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                            JOptionPane.showMessageDialog(this,"Erreur survenue","Erreur",JOptionPane.ERROR_MESSAGE);              
                        }
                    }     
        }  
        else if(evt.getClickCount()==2){
                    int index = listContacts.getSelectedIndex();
                        if(index != -1) {
                            try {
                                String rName = (String)listModel.getElementAt(listContacts.getSelectedIndex());
                                performWizzer(rName);
                            } catch (ControllerPerformException ex) {
                                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                                JOptionPane.showMessageDialog(this,"Wizz indisponible","Erreur",JOptionPane.ERROR_MESSAGE);              
                            }
                         }
        }  
    }//GEN-LAST:event_listContactsMouseClicked

    private void statusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_statusActionPerformed
        try {
            // TODO add your handling code here:
            String show= status.getSelectedItem().toString();
            labelStatus.setText(show);

            if(show.equalsIgnoreCase("Connecté")){
                labelStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Ressources/images/online.png"))); // NOI18N
            }
            if(show.equalsIgnoreCase("Absent")){
                labelStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Ressources/images/away.png"))); // NOI18N
            }
            performStatus(show);
        } catch (ControllerPerformException ex) {
            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this,"Changement de statut indisponible","Erreur",JOptionPane.ERROR_MESSAGE);              

        }    
    }//GEN-LAST:event_statusActionPerformed

    private void areaMsgKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_areaMsgKeyReleased
        // TODO add your handling code here:
        String rName=null;
        Onglet currentOnglet = (Onglet)tabbedPane.getSelectedComponent();
        if(currentOnglet != null)  rName = currentOnglet.getDestination();
        if(rName !=null && evt.getKeyCode()!= KeyEvent.VK_ENTER){
            try {
                    performComposing(rName,false);
            } catch (ControllerPerformException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else if(rName !=null && evt.getKeyCode()== KeyEvent.VK_ENTER){     
            try {                
                this.sendMsg();
            } catch (BadLocationException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(this,"Une erreur est survenue","Erreur",JOptionPane.ERROR_MESSAGE);    
            }
        }     
    }//GEN-LAST:event_areaMsgKeyReleased

   
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea areaMsg;
    private javax.swing.JLabel barreEtat;
    private javax.swing.JButton buttonFile;
    private javax.swing.JButton buttonSend;
    private javax.swing.JMenuItem itemConnexion;
    private javax.swing.JMenuItem itemDeconnexion;
    private javax.swing.JLabel labelStatus;
    private javax.swing.JLabel labelWelcome;
    private javax.swing.JList listContacts;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu menuFichier;
    private javax.swing.JMenu menuHelp;
    private javax.swing.JScrollPane scrollBarList;
    private javax.swing.JScrollPane scrollBarMsg;
    private javax.swing.JComboBox status;
    private javax.swing.JTabbedPane tabbedPane;
    // End of variables declaration//GEN-END:variables


    private colorOnglet color;
    public DefaultListModel listModel;
    private String login;
    private boolean isConnected;
    private ChatSystem chatSys;
    private ChatController chatCtrl;
    private AboutDialog dialog ;
    private HashMap<String,Integer> tabMap;
    private int nbTab;
    private ChatPanel panels; 
     /**
    * Gère la connexion d'un utilisateur local
    * @param login Login fourni par l'utilisateur
    * @throws ControllerPerformException
    */
    @Override
    public void performConnect(String login) throws ControllerPerformException {
        this.login=login;
        isConnected=true;
        labelStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Ressources/images/online.png"))); // NOI18N
        labelStatus.setText("Connecté");
        chatCtrl.performConnect(login);
    }
     /**
    * Gère la déconnexion de l'utilisateur local
    * @throws ControllerPerformException
    */
    @Override
    public void performDisonnect() throws ControllerPerformException {
             
             int reponse = JOptionPane.showConfirmDialog(this,
					       "Voulez vous vraiment vous déconnecter ?",
					       "Avertissment", 
					        JOptionPane.YES_NO_OPTION);
             if (reponse == JOptionPane.YES_OPTION) {
                    listModel.clear();
                    panels.clear();
                    listContacts.setListData(panels.getListPanels());
                    this.color.stopActivity();

                    tabbedPane.removeAll();
                    tabMap.clear();
                    nbTab=0;
                    isConnected=false;

                    chatCtrl.performDisonnect();
                    chatSys.deconnexion();

             }
    }
     /**
    * Gère l'envoi d'un message
    * @param remoteLogin Login de l'utilisateur distant à qui envoyer le message
    * @param messageText Message à envoyer
    * @throws ControllerPerformException
    */
    @Override
    public void performChat(String remoteLogin, String messageText) throws ControllerPerformException {
        chatCtrl.performChat(remoteLogin, messageText);
    }
    /**
    * Gère l'envoi d'une demande de transfert de fichier
    * @param file Pathfile representant le fichier à transferer
    * @param remoteLogin Login de l'utilisateur distant à qui envoyer le message
    * @throws ControllerPerformException
    */
    @Override
    public void performFileRequest(PathFile file, String remoteLogin) throws ControllerPerformException {
        chatCtrl.performFileRequest(file, remoteLogin);
    }
    /**
    * Gère l'envoi d'une reponse de transfert de fichier
    * @param remoteLogin
    * @param accept <code>true</code> si demande accepté 
    *               <code>false</code> sinon
    * @throws ControllerPerformException
    */
    @Override
    public void performFileResponse(String remoteLogin, boolean accept) throws ControllerPerformException {
        chatCtrl.performFileResponse(remoteLogin, accept);
    }
    /**
    * Gère l'envoi d'un wizz à un utilisateur distant
    * @param remoteLogin Login de l'utilisateur distant à qui envoyer le wizz
    * @throws ControllerPerformException
    */
    @Override
    public void performWizzer(String remoteLogin) throws ControllerPerformException {
        chatCtrl.performWizzer(remoteLogin);
    }
     /**
    * Gère l'envoi d'un changement de status
    * @param show Status de l'utilisateur
    * @throws ControllerPerformException   
    */
    @Override
    public void performStatus(String show) throws ControllerPerformException {
        chatCtrl.performStatus(show);
    }
    /**
    * Gère l'envoi d'une notification d'ecriture 
    * @param remoteLogin  Login de l'utilisateur distant à qui envoyer la notification
    * @throws ControllerPerformException
    */
    @Override
    public void performComposing(String remoteLogin,boolean isWriting) throws ControllerPerformException {
        chatCtrl.performComposing(remoteLogin,isWriting);
    }
    /**
    * Ajoute un utilisateur distant à la liste de contacts
    * @param remoteLogin Login de l'utilisateur distant
    */
    @Override
    public void addElement(String remoteLogin) {
        if(!listModel.contains(remoteLogin)){
             panels.insertOnlinePanel(remoteLogin);
             listModel.addElement(remoteLogin);
             listContacts.setListData(panels.getListPanels());
        }
       
    }
    /**
    * Supprime un utilisateur distant de la liste de contacts
    * @param remoteLogin  Login de l'utilisateur distant à supprimer
    */
    @Override
    public void removeElement(String remoteLogin) {
        if(listModel.contains(remoteLogin)){
            listModel.removeElement(remoteLogin);
            //suppression de l'onglet  teste valeur index
            Integer index =tabMap.get(remoteLogin);
            if(index !=null){
                tabbedPane.remove(index.intValue());
                tabMap.remove(remoteLogin);
                nbTab--;
            }

            panels.deletePanel(remoteLogin);
            listContacts.setListData(panels.getListPanels());
        }
        if(listModel.isEmpty())
            tabbedPane.removeAll();
    }

    /**
    * Affiche un message de bienvenue
    */
    public void setWelcome(){
       labelWelcome.setText("\nBienvenue "+login +" ! \n");;
    }
     /**
    * indique si l'utilisateur est connecté au systeme 
    * @return <code>true</code> si utilisateur est connecté
    *           <code>false</code> sinon 
    */
    @Override
    public boolean isConnected() {
        return isConnected;
    }
    /**
    * Affecte un ChatController à notre ChatNetwork
    * @param controller ChatController à affecter
    */
    public void setController(ChatController controller) {
        this.chatCtrl = controller;
    }
     /**
    * Affecte un ChatSystem à notre ChatNetwork
    * @param ChatSys ChatSystem à affecter
    */
    public void setChatSys(ChatSystem ChatSys) {
        this.chatSys = ChatSys;
    }
    /**
    * Réactualise l'affichage de la conversation
    * @param sMsg Message reçu d'un utilisateur distant
    * @param rUser Login de l'utilisateur distant qui a envoyé le message
    */
    @Override
    public void refreshMsg(String sMsg, String rUser) {  
        Integer index =tabMap.get(rUser);
        if(index==null){
            try {
                Onglet onglet = new Onglet(rUser);
                tabbedPane.insertTab(rUser, null, onglet, rUser, nbTab);
                tabMap.put(rUser, Integer.valueOf(nbTab++));
                this.color.startActivity();

            } catch (IOException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
            } catch (URISyntaxException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        index =tabMap.get(rUser);
        if(index != null && listModel.contains(rUser)){
            try {

                String message = rUser+" > "+sMsg+"\n" ;
                Onglet o = (Onglet) tabbedPane.getComponent(index.intValue());
                o.deleteComposing(rUser);
                o.insertRemoteString(message);
                // Changer la couleur de l'onglet 
                tabbedPane.setBackgroundAt(index.intValue(), Color.ORANGE);
                tabbedPane.setToolTipTextAt(index.intValue(), "Message recu");
            } catch (BadLocationException ex) {
                Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(this,"Erreur reception message","Erreur",JOptionPane.ERROR_MESSAGE);              
            }
        }
        else if(!listModel.contains(rUser)){
           this.addElement(rUser);
           refreshMsg(sMsg, rUser);
        }
        AudioSound msg= new AudioSound(ChatGUI.class.getResource("/Ressources/sons/message.wav"));
        new Thread(msg).start();
    }
   /**
    * Gère la reception d'une demande de transfert de fichier
    * @param pathfile       PathFile du fichier à transferer
    * @param remoteLogin    Login de l'utilisteur distant
    * @see PathFile
    */
    @Override
    public void refreshFileRequest(PathFile pathfile, String remoteLogin) {
         
        AudioSound file= new AudioSound(ChatGUI.class.getResource("/Ressources/sons/asker.wav"));
        new Thread(file).start();
        try {
            Image img = (new ImageIcon(getClass().getResource("/Ressources/images/transfert.gif"))).getImage();
            Icon  app = new ImageIcon(img.getScaledInstance(30, 30, 30));

            String sToDisplay= remoteLogin+" souhaite vous transferer le fichier "+pathfile.getName();
            String sTitle = "Transfert de fichier";

            int isOK = JOptionPane.showConfirmDialog(this, sToDisplay, sTitle,
                       JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,app);    

            boolean bAccept = (isOK==JOptionPane.OK_OPTION)? true:false ;

            if (bAccept) performFileResponse(remoteLogin, bAccept);
        } catch (ControllerPerformException ex) {
            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
           JOptionPane.showMessageDialog(this,"Erreur transfert fichier","Erreur",JOptionPane.ERROR_MESSAGE);              

        }
    }
     /**
    * Traite une reponse d'une deamnde de transfert de fichier
    * @param haveAccept  <code>true</code> si utilisateur accepte de recevoir un fichier
    *           <code>false</code> sinon 
    */
    @Override
    public void refreshFileResponse(boolean haveAccept) {
        if(haveAccept){
            barreEtat.setText("Transfert de fichier en cours . . .");
        }
    }
    /**
    * Wizz la fenetre d'un utilisateur distant
    * @param remoteLogin  Login de l'utilisateur distant
    */
    @Override
    public void refreshWizz(String remoteLogin) {
        barreEtat.setText(remoteLogin+" vous a envoyé un wizz . . .");
        AudioSound wizz= new AudioSound(ChatGUI.class.getResource("/Ressources/sons/wizz.wav"));
        new Thread(wizz).start();
        Wizzer wizzer = new Wizzer(this);
    }
    /**
    * Notification de presence
    * @param remoteLogin  Login de l'utilisateur distant
    * @param status       Status de l'utilisateur local
    */
    @Override
    public void refreshPresence(String remoteLogin, String status) {
        //suppression du user
        panels.deletePanel(remoteLogin);
        if(status.equals((Status.AWAY).toString())){
            panels.insertAwayPanel(remoteLogin);
        }else if(status.equals((Status.CHAT).toString())){
            panels.insertOnlinePanel(remoteLogin);
        }
        listContacts.setListData(panels.getListPanels());
        barreEtat.setText(remoteLogin+" est désormais "+status+". . .");
    }
    /**
    * Gère la reception d'une notification d'ecriture 
    * @param remoteLogin Login de l'utilisateur distant
    * @param isWriting   <code>true</code> si utilisateur ecrit 
    *                  <code>false</code> sinon 
    * @throws ControllerReceivedException
    */
    @Override
    public void refreshComposing(String remoteLogin,boolean isWriting){
        try {
            barreEtat.setText(remoteLogin+" est entrain d'ecrire un message ..");
            Integer index =tabMap.get(remoteLogin);
            if(nbTab!=0 && index != null){
                Onglet currentOnglet = (Onglet)tabbedPane.getComponent(index.intValue());
                if(currentOnglet != null && currentOnglet.getDestination().equalsIgnoreCase(remoteLogin)) 
                    if(isWriting) currentOnglet.insertComposing(remoteLogin);
                    else  currentOnglet.deleteComposing(remoteLogin);
            }          
        } catch (BadLocationException ex) {
            Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
    * Récupère le message écrit et le destinataire associé et le transmet au contrôleur
    */
    private void sendMsg() throws BadLocationException{
          String msg = areaMsg.getText();
          //recuperer uniquement le currentab
          if(listContacts.getSelectedIndex()!= -1){
                String rName = (String)listModel.getElementAt(listContacts.getSelectedIndex());
                this.messageAvailable(rName, msg);
          }
          else if(tabbedPane.getSelectedComponent()!=null){
              //recuperation de l'onglet courant
               Onglet currentOnglet = (Onglet)tabbedPane.getSelectedComponent();
               String rName = currentOnglet.getDestination();
               this.messageAvailable(rName, msg);
          }
          else{
                JOptionPane.showMessageDialog(this,"Selectionnez un contact dans la liste","Aucun contact",JOptionPane.ERROR_MESSAGE);        
          }
    }
    
    private void messageAvailable(String rName,String msg) throws BadLocationException{
        if(!msg.equals("\n") && MessageSettings.checkMessage(msg)){                
                try {
                    areaMsg.setText("");                  
                    String message = "Moi > "+msg;
                    Integer index =tabMap.get(rName);
                    Onglet o = (Onglet) tabbedPane.getComponent(index.intValue());
                    o.insertLocalString(message);
                    barreEtat.setText(login+" est connecté");
                    performChat(rName, msg);
                } catch (ControllerPerformException ex) {
                    Logger.getLogger(ChatGUI.class.getName()).log(Level.SEVERE, null, ex);
                    JOptionPane.showMessageDialog(this,"Une erreur est survenue","Erreur",JOptionPane.ERROR_MESSAGE);    
                }
            }
        else{
            JOptionPane.showMessageDialog(this,"Message non conforme","Erreur",JOptionPane.ERROR_MESSAGE);    
        }
    }
}
